/*
 * redmicro all Copyright (c)

 * Created by seeker910 on 2014/12/29.
 *
 * 对于不要显示但需要保存但数据（如：主键）的数据建议使用隐藏控件，有利于数据专递。
 *
 */
Rsd.define('Rsd.widget.ModelForm', {
    extend: 'Rsd.container.Form',
    requires: [
        'Rsd.container.FieldSet',
        'Rsd.form.Label',
        'Rsd.form.Button',
        'Rsd.form.Text',
        'Rsd.form.TextArea',
        'Rsd.form.TextFK',
        'Rsd.form.Password',
        'Rsd.form.Secret',
        'Rsd.form.Privacy',
        'Rsd.form.Date',
        'Rsd.form.Time',
        'Rsd.form.Timestamp',
        'Rsd.form.Number',
        'Rsd.form.Hidden',
        'Rsd.form.CheckBox',
        'Rsd.form.Radio',
        'Rsd.form.ComboBoxEnum',
        'Rsd.form.MulitiSelectEnum',
        'Rsd.form.Picker',
        'Rsd.form.Image',
        'Rsd.form.Images', 
        'Rsd.form.Link',
        'Rsd.form.Json'
    ],
    xtype: 'model-form',
    layout: 'fit',
    margin: '10 0 10 0',
    height: 'auto',
    //fields 已加载
    //fieldsHasLoaded:false,
    readonly: true,
    errorList: [],
    /*
    * 对于不要显示但需要保存但数据（如：主键）的数据建议使用隐藏控件，有利于数据专递。
    * */
    fields: [],
    /**
     * 
     */
    fieldWidth: '45%',
    //最后一次加载的数据对象
    //data:{}, 
    items: [
        {
            xtype: 'fieldset',
            header:null,
            legend: '明 细 信 息',
            height: "100%",
            items: [], 
            layout: { type: 'vbox', align: 'left' }
        }
    ],
    /**
     * 对接fieldset  header
     */
    //toolBar:{},
    /*
     * */
    constructor: function ModelForm(config) {
        config = config || {};
        this.apply(config);

        this.items[0].legend = this.legend; 
    },
    /*
    * */
    onAfterRender: function onAfterRender() {

        var me = this;
        
        setTimeout(function () {
            
            me.loadFields();//render 之后会执行doLayout

            //出现滚动条 重新设置 该控件高度，不让该控件出现滚动条，让滚动条出现在该控件父控件中
           if(me.items[0].body.scrollHeight > me.items[0].body.clientHeight) 
           {
               var _scrollHeight = me.items[0].body.scrollHeight + (me.items[0].legend ? 100 : 45);
          
               me.height = _scrollHeight;
           }
           
       }, 50);

       me.callParent(); 
    },
    /** 
    * @description 加载字段,加载完字段，后会自动加载数据
    * */
    loadFields: function loadFields() {

        //debugger; 
        var me = this;
        if (me.fieldsHasLoaded) {
            return;
        }
        //debugger;
        if (me.items[0] == null || me.items[0] == undefined) {

            return;
        }
        var _readonly = me.readonly;

        if (_readonly === undefined || _readonly==null) {
            _readonly = false;
        }

        var formfields = me.fields;
        var _w = 0;
        var _width = me.getWidth() || me.parent.getWidth();
        //console.log(formfields);
        if (formfields && formfields.length > 0) {

            var fields = formfields;
            var _field = null; 
            for (var f in fields) {
                //debugger;
                if(fields[f]['onField'])
                {
                    continue;
                }
                try {
                    _field = Rsd.clone(fields[f]);

                    var _dataIndex = _field.dataIndex || _field.dataindex || _field.name;
                    var _defaultXtype = "text";
                    if(!_dataIndex && !_field.xtype)
                    { 
                         _defaultXtype =  "component-x";
                    }

                    if (_field.label) {
                        _field.label.content = _field.label.content || _field.label.text;
                        var _lbl_style = {};
                        switch(_field.label.position)
                        {
                            case "top":
                            case "bottom":
                                    {
                                        _lbl_style = {};
                                        break;
                                    }
                            case "left":
                             case "right":
                                    {
                                        _lbl_style = { lineHeight: _field.height || 32 };
                                        break;
                                    }
                                   
                        }
                        _field.label.style = Rsd.apply(_lbl_style, _field.label.style);
                        delete _field.label.text;
                    }
                    if (_field.hasOwnProperty('readonly')) {
                        _field.readonly = (_readonly ? true : _field.readonly);
                    }
                    else {
                        _field.readonly = _readonly;
                    }
                    var _h = 0;
                    if (_field.xtype != 'hidden') {
                        _h = _field.height || 32;
                    }
                    _w += _field.width || 0;
                    if (_field.width && _width && _w < _width) {
                    }
                    else {
                        _w = _field.width || 0; 
                    }
                    
                    var _new_field = Rsd.apply(
                        {
                            id: _field.id || _field.name || '',
                            dataIndex: _dataIndex,
                            height: _h,
                            width: me.fieldWidth || '45%',
                            tabIndex: f,
                            margin: '4 0 4 0',
                            xtype: _defaultXtype
                        }, _field);
 
                    if (me.items[0] instanceof Rsd.container.Component) {
                        me.items[0].add(_new_field);
                    }
                    else {
                        me.items[0].items.push(_new_field);
                    }
                }
                catch (ex) {
                    console.error(ex);
                }
            }
            me.doLayout();
            me.fieldsHasLoaded = true;
            
        }
 
        //fieldsHasLoaded == false 时 ，数据不会被加载
        me.loadData();

        return this;
    },
    /**
     * 
     * @param {*} editable true is edit mode ,flase is view mode
     */
    setMode:function setMode(editable)
    {
        
        var me = this;
        if(me.readonly)
        {
            return;
        }
        var _items = me.items[0].items;
        for(var i in _items)
        {
            var item = _items[i];
            if(item.readonly)
            {
                continue;
            }

            if(Rsd.isFunction(item.setMode))
            {
                //个性化处理
                item.setMode(editable);
                continue;
            }
            //console.log(item);
            //通用处理
            if(editable)
            {
                item.ctrl.element.removeAttribute('readonly');
                item.ctrl.element.style.borderWidth = '';
            }
            else
            {
                item.ctrl.element.setAttribute('readonly',true);
                item.ctrl.element.style.borderWidth = '0px';
            }
            
        }
    },
    /**
     * @description 验证控件输入值 是否有效
     *  */
    checkRecord: function checkRecord() {

        var _item = null;
        var _form = this.items[0];
        this.errorList = [];
        for (var i = 0; i < _form.items.length; i++) {
            _item = _form.items[i];

            if (!Rsd.isFunction(_item.checkValue) ) {
                if(_item.xtype !=='component-x'  || _item.xtype !=='container' )
                {
                    continue;
                }
                console.warn('Control [' + _item.$className + '('+_item.xtype+')] has no function \'checkValue\'.');
                continue;
            }

            try {
                if (!_item.checkValue()) {
                    this.errorList.push(_item.getError());
                }
            }
            catch (err) {
                console.error(err);
            }

        }

        return this.errorList.length == 0;
    },
    /**
    * @description 错误消息处理
    * @description handler:方法注入
    * */
    showError: function showError(handler) {

        if (this.errorList.length > 0) {
            if (handler) {
                handler.call(this, [this.errorList]);
            }
            else {
                Rsd.alert('错误提示', this.errorList);
            }
        }

    },
    /** 
    * @description 将控件获取到的数据合并到 参数obj 或data 中返回；排除readonly 和 hidden 控件
    * @description 如果使用该方法获取记录提交服务端，应先调用checkRecord方法验证form的数据是否全部有效；
     * @param {*} obj 表单数据对象默认值
     * @returns 
     */
    getRecord: function getRecord(obj) {

        //数据源
        var data = obj || this.data || {}; 
        //克隆一个新对象，防止源数据被干扰
        var _obj = Rsd.clone(data);
       
        var me = this;
        var _item = null;
        var _form = me.items[0];

        for (var i = 0; i < _form.items.length; i++) {
            _item = _form.items[i]; 
            if (_item.readonly && _item.xtype != 'hidden') {
                //console.log('model_form get redcord',_item.dataIndex,_item.xtype);
                //控件 状态 为 readonly 模式时，不获取数据，如果对象存在默认数据，可用过参数obj传递
                continue; 
            }
            var _dataIndex = _item.dataIndex || _item.dataindex || _item.name;
            if (Rsd.isEmpty(_dataIndex)) {
                continue;
            }
            //
            if(Rsd.isFunction(_item.getValue))
            {
                _obj[_dataIndex] = _item.getValue();
                data[_dataIndex] = _item.getValue();//修改数据源

                if(_obj[_dataIndex] != null && _obj[_dataIndex] != undefined)
                {
                    _obj[_dataIndex] = encodeURIComponent(_obj[_dataIndex]);//编码数据，用于API接口提交
                }
            } 
        }
        //console.log('model_form get redcord',_obj);
        return _obj;

    },
    /**
    *
    * @description 获取字段值
    * */
    getFieldValue: function getFieldValue(name) {
        var _obj = this.data || {};
        var me = this;
        var _item = null;
        var _form = me.items[0];

        for (var i = 0; i < _form.items.length; i++) {
            _item = _form.items[i];
            if (_item.readonly) {
                continue;
            }
            if(Rsd.isFunction(_item.getValue))
            {
                _obj[_item.dataIndex || _item.dataindex] = _item.getValue();
            }
            
        }

        return _obj[name];
    },
    /**
     * 获取页面当前所有控件数据，不验证，不编码，不合并原始数据
     */
    getData:function getData()
    {  
        var me = this; 
         //数据源
        var data = this.data || {}; 
        //克隆一个新对象，防止源数据被干扰
        var _obj = Rsd.clone(data);
        var _item = null;
        var _form = me.items[0];

        for (var i = 0; i < _form.items.length; i++) {
            _item = _form.items[i]; 
             
            var _dataIndex = _item.dataIndex || _item.dataindex || _item.name;
            if (Rsd.isEmpty(_dataIndex)) {
                continue;
            }
            if(Rsd.isFunction(_item.getValue))
            {
                _obj[_dataIndex] = _item.getValue();
                data[_dataIndex] = _item.getValue();//修改数据源

                if(_obj[_dataIndex] != null && _obj[_dataIndex] != undefined)
                {
                    _obj[_dataIndex] = _obj[_dataIndex] ; 
                }
            } 
        }
        //console.log('model_form get data',_obj);
        return _obj;
    },
    /**
     *@description 
     * */
    loadData: function loadData(record) {

        var _r = record || this.data || {};
        //console.log('modelForm data is ',_r);
        this.data = _r;
        //fields  暂未加载 不加载数据,更新this.data
        if (this.fieldsHasLoaded == false) {
            return;
        }
      
        var me = this;
        var _item = null;
        var _dataIndex = null;
        for (var i = 0; i < me.items[0].items.length; i++) {
            _item = me.items[0].items[i];
            if(!Rsd.isFunction(_item.setValue))
            {
                continue;
            }
            try {
                _dataIndex = _item.dataIndex || _item.dataindex || _item.name ||'';
                if(_dataIndex)
                {
                    //console.log('model form',_dataIndex,Rsd.hasProperty(_r, _dataIndex),_r);
                    //_item.setDisabled(!Rsd.hasProperty(_r, _dataIndex));
                    if (_r[_dataIndex] !== undefined) {
                        _item.setValue(_r[_dataIndex],_r); 
                    }
                    else 
                    {
                        //支持persion.school.class格式子对象查找
                        var list = _dataIndex.split('.');
                        var j = 0;
                        var _p = _r;
                        while (list.length > 1 && j < list.length && Rsd.hasProperty(_p, list[j])) {
                            _p = _p[list[j]];
                            j++;
                        }
                        if (j == list.length) {
                            
                            _item.setValue(_p,decodeURIComponent(_r));
                        }
                    }
                }
                
            }
            catch (e) {
                console.error(e);
            }

        }
        return this;
    },

    /*
    *@param key:index or name or id  or xtype
    * */
    getFieldControl: function getFieldControl(key) {
        
        if (Rsd.isNumber(key)) {
            //console.log(key,this.items[0].items.length);
            return this.items[0].items[key];
        }
        return this.items[0].getItemByName(key) || this.items[0].getItemById(key) || this.items[0].getItemByXtype(key);
    },
    /**
     * 
     */
    getScrollHeight: function getScrollHeight() {
        return this.items[0].body.scrollHeight;
    }


}, function (type) {

    var _toolBarGetter = function () {

        if (!this.hasOwnProperty('__toolBar')) {
            
        }
        return this.items[0].header;
    };
    var _toolBarSetter = function (value) {

        this.items[0].header = value;
        return;

    };
    this.defineProperty(type, "toolBar", _toolBarGetter, _toolBarSetter, true);


    var _dataGetter = function () {

        if (!this.hasOwnProperty('__data')) {
            this.__data = {};
        }
        return this.__data;
    };
    var _dataSetter = function (value) {

        this.__data = value;
        return;

    };
    this.defineProperty(type, "data", _dataGetter, _dataSetter, true);

    //
    this.defineProperty(type, "fieldsHasLoaded", function () {

        if (!this.hasOwnProperty('__isLoaded')) {
            this.__isLoaded = false;
        }
        return this.__isLoaded;

    }, function (value) {
        this.__isLoaded = value;
    }, false);



});
